using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SiKuma.ScreenSystemLibrary
{
    public abstract class MenuEntry
    {
        public enum EntryState
        {
            Normal,
            Highlight,
            Selected
        }
        private MenuEntry.EntryState state;
        
        public Point numberOfEntries;
        
        private Dictionary<bool, Rectangle> displayRegion;
        private bool hasSubMenu;
        private Color color = Color.White;
        private float scale = 1f;
        private float opacity = 1f;
        
        public event EventHandler OnHighlight;
        public event EventHandler OnNormal;
        public event EventHandler Selected;
        
        public MenuEntry.EntryState State
        {
            get
            {
                return this.state;
            }
        }
        
        public string EntryTitle
        {
            get;
            set;
        }
        
        public string EntryDescription
        {
            get;
            set;
        }
        
        public Point EntryPadding
        {
            get;
            private set;
        }
        
        public Texture2D EntryTexture
        {
            get;
            private set;
        }
        
        public Rectangle BoundingRectangle
        {
            get;
            private set;
        }
        
        public bool IsSheet
        {
            get
            {
                return this.numberOfEntries.X == 1 && this.numberOfEntries.Y == 1;
            }
        }
        
        public Vector2 DefaultPosition
        {
            get;
            private set;
        }
        
        public Vector2 Position
        {
            get;
            set;
        }
        
        public Vector2 Velocity
        {
            get;
            set;
        }
        
        public Vector2 Acceleration
        {
            get;
            set;
        }
        
        public MenuScreen ParentMenu
        {
            get;
            set;
        }
        
        public MenuScreen SubMenu
        {
            get;
            private set;
        }
        
        public bool HasSubMenu
        {
            get
            {
                return this.hasSubMenu;
            }
        }
        
        public Color Color
        {
            get
            {
                return this.color;
            }
            set
            {
                this.color = value;
            }
        }
        
        public float Scale
        {
            get
            {
                return this.scale;
            }
            set
            {
                this.scale = value;
            }
        }
        
        public float Opacity
        {
            get
            {
                return this.opacity;
            }
            set
            {
                this.opacity = value;
            }
        }
        
        public virtual void Highlight()
        {
            this.Color = this.ParentMenu.Highlighted;
            this.state = MenuEntry.EntryState.Highlight;
            if (this.OnHighlight != null)
            {
                this.OnHighlight(this, EventArgs.Empty);
            }
        }
        
        public virtual void Normal()
        {
            this.Color = this.ParentMenu.Normal;
            this.state = MenuEntry.EntryState.Normal;
            if (this.OnNormal != null)
            {
                this.OnNormal(this, EventArgs.Empty);
            }
        }
        
        public virtual void Select()
        {
            if (this.SubMenu != null)
            {
                this.state = MenuEntry.EntryState.Selected;
                this.Color = this.ParentMenu.Selected;
                this.SubMenu.ActivateScreen();
                this.ParentMenu.ScreenSystem.AddScreen(this.SubMenu);
                this.ParentMenu.FreezeScreen();
                this.ParentMenu.HideMouse();
                this.SubMenu.EnableMouse(this.ParentMenu.MouseTexture);
            }
            if (this.Selected != null)
            {
                this.state = MenuEntry.EntryState.Selected;
                this.Color = this.ParentMenu.Selected;
                this.Selected(this, EventArgs.Empty);
            }
        }
        
        protected MenuEntry()
        {
            this.BoundingRectangle = new Rectangle(0, 0, 0, 0);
        }
        
        protected MenuEntry(MenuScreen screen, string title)
        {
            this.color = screen.Normal;
            this.ParentMenu = screen;
            this.EntryTitle = title;
            this.BoundingRectangle = new Rectangle(0, 0, 0, 0);
        }
        
        protected MenuEntry(MenuScreen screen, Texture2D texture)
        {
            this.color = screen.Normal;
            this.ParentMenu = screen;
            this.EntryTexture = texture;
            this.BoundingRectangle = new Rectangle(0, 0, 0, 0);
        }
        
        protected MenuEntry(MenuScreen screen, string title, Texture2D texture)
        {
            this.color = screen.Normal;
            this.ParentMenu = screen;
            this.EntryTitle = title;
            this.EntryTexture = texture;
            this.BoundingRectangle = new Rectangle(0, 0, 0, 0);
        }
        
        public void UpdateEntry(GameTime gameTime)
        {
            this.Update(gameTime);
            SpriteFont spriteFont = this.ParentMenu.SpriteFont;
            Vector2 vector = (spriteFont == null) ? Vector2.Zero : spriteFont.MeasureString(this.EntryTitle);
            int width = (int)((this.EntryTexture == null) ? vector.X : ((float)this.EntryTexture.Width));
            int height = (int)((this.EntryTexture == null) ? vector.Y : ((float)this.EntryTexture.Height));
            this.BoundingRectangle = new Rectangle((int)this.Position.X, (int)this.Position.Y, width, height);
        }
        
        public abstract void Update(GameTime gameTime);
        public abstract void AnimateHighlighted(GameTime gameTime);
        
        public virtual void Draw(GameTime gameTime, bool isSelected)
        {
            SpriteBatch spriteBatch = this.ParentMenu.ScreenSystem.SpriteBatch;
            SpriteFont spriteFont = this.ParentMenu.SpriteFont;
            Vector2 vector = new Vector2(this.Position.X, this.Position.Y);
            if (this.EntryTexture != null)
            {
                if (this.IsSheet)
                {
                    spriteBatch.Draw(this.EntryTexture, this.Position, Color.White * this.opacity);
                }
                else
                {
                    if (this.displayRegion != null)
                    {
                        spriteBatch.Draw(this.EntryTexture, this.Position, new Rectangle?(this.displayRegion[isSelected]), Color.White * this.opacity);
                    }
                }
                if (spriteFont != null && this.EntryTitle.Length > 0)
                {
                    Vector2 vector2 = spriteFont.MeasureString(this.EntryTitle);
                    float x = (this.EntryPadding.X == 0) ? ((float)(this.EntryTexture.Width / 2) - vector2.X / 2f) : ((float)this.EntryPadding.X);
                    float y = (this.EntryPadding.Y == 0) ? ((float)(this.EntryTexture.Height / 2) - vector2.Y / 2f) : ((float)this.EntryPadding.Y);
                    vector += new Vector2(x, y);
                    spriteBatch.DrawString(spriteFont, this.EntryTitle, vector, this.color * this.opacity);
                    return;
                }
            }
            else
            {
                if (spriteFont != null && this.EntryTitle.Length > 0)
                {
                    spriteBatch.DrawString(spriteFont, this.EntryTitle, vector, this.color * this.opacity, 0f, Vector2.Zero, this.scale, SpriteEffects.None, 0f);
                }
            }
        }
        
        public virtual void DrawDescription(GameTime gameTime, Rectangle boxPosition, Point padding, Color textColor, float scale)
        {
            SpriteBatch spriteBatch = this.ParentMenu.ScreenSystem.SpriteBatch;
            SpriteFont spriteFont = this.ParentMenu.SpriteFont;
            if (spriteFont != null)
            {
                Vector2 vector2 = spriteFont.MeasureString(this.EntryDescription) * scale;
                float num = (float)padding.X;
                float num2 = (float)padding.Y;
                Vector2 position = new Vector2((float)boxPosition.X + num, (float)boxPosition.Y + num2);
                spriteBatch.DrawString(spriteFont, this.EntryDescription, position, textColor, 0f, Vector2.Zero, scale, SpriteEffects.None, 1f);
            }
        }
        
        public void AddSubMenu(MenuScreen subMenu)
        {
            this.hasSubMenu = true;
            this.SubMenu = subMenu;
        }
        
        public void SetRelativePosition(Vector2 relativePosition, MenuEntry entry, bool defaultPosition)
        {
            Vector2 value = new Vector2(entry.Position.X, entry.Position.Y);
            if (entry.EntryTexture != null)
            {
                value.Y += (float)entry.EntryTexture.Height;
            }
            this.SetPosition(Vector2.Add(value, relativePosition), defaultPosition);
        }
        
        public void SetRelativePosition(Vector2 relativeDefaultPosition, Vector2 relativeCurrentPosition, MenuEntry entry)
        {
            Vector2 value = new Vector2(entry.DefaultPosition.X, entry.DefaultPosition.Y);
            Vector2 value2 = new Vector2(entry.Position.X, entry.Position.Y);
            if (entry.EntryTexture != null)
            {
                value.Y += (float)entry.EntryTexture.Height;
                value2.Y += (float)entry.EntryTexture.Height;
            }
            this.SetPosition(Vector2.Add(value, relativeDefaultPosition), Vector2.Add(value2, relativeCurrentPosition));
        }
        
        public void SetPosition(Vector2 position, bool defaultPosition)
        {
            if (defaultPosition)
            {
                this.DefaultPosition = position;
            }
            this.Position = position;
        }
        
        public void SetPosition(Vector2 defaultPosition, Vector2 current)
        {
            this.DefaultPosition = defaultPosition;
            this.Position = current;
        }
        
        public void AddTexture(Texture2D texture)
        {
            this.EntryTexture = texture;
            this.numberOfEntries = new Point(1, 1);
        }
        
        public void AddTexture(Texture2D texture, int numX, int numY, Rectangle selectedEntry, Rectangle normalEntry)
        {
            this.EntryTexture = texture;
            this.numberOfEntries = new Point(numX, numY);
            this.displayRegion = new Dictionary<bool, Rectangle>();
            this.displayRegion.Add(true, selectedEntry);
            this.displayRegion.Add(false, normalEntry);
        }
        
        public void AddPadding(int all)
        {
            this.EntryPadding = new Point(all, all);
        }
        
        public void AddPadding(int left, int top)
        {
            this.EntryPadding = new Point(left, top);
        }
    }
}
